package com.yanqu.road.server.gameplayer.module.bulletscreen;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.bulletscreen.ActivityBarrageMessage;
import com.yanqu.road.pb.activity.BulletScreenProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.manger.activity.bulletscreen.ActivityBulletScreenMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.LocalDateTimeHelper;
import com.yanqu.road.utils.date.DateHelper;
import org.apache.mina.util.ConcurrentHashSet;

import java.util.*;
import java.util.concurrent.atomic.AtomicLong;

public class ActivityBulletScreen {

    private ActivityInfo activityInfo;

    //弹幕-----------------
    private Object barrageLock = new Object();

    private AtomicLong contentId;

    private List<ActivityBarrageMessage> messageList;

    private Set<Long> userIdSet = new ConcurrentHashSet<>();

    private int newNum = 0;

    //上次推送ID
    private long lastSyncContentId;


    public ActivityBulletScreen(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;
    }

    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public void setActivityInfo(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;
    }

    public void init(){
        /** 消息不入库
        int activityId = activityInfo.getActivityId();
        long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp();
        List<ActivityBarrageMessage> tempMessageList = BulletScreenBusiness.getActivityBarrageMessageList(activityId, zeroTime);
        if(tempMessageList.size() == 0){
            contentId = new AtomicLong(0);
        }else {
            long maxId = BulletScreenBusiness.getMaxContentId(activityId);
            contentId = new AtomicLong(maxId);
        }*/
        contentId = new AtomicLong(0);
        List<ActivityBarrageMessage> tempMessageList = new ArrayList<>();
        messageList = tempMessageList;
        userIdSet = new ConcurrentHashSet<>();
        newNum = 0;
        lastSyncContentId = 0;
    }

    /**
     * 弹幕
     * @param content
     * @param userId
     * @return
     */
    public ActivityBarrageMessage addBarrageMessage(String content, long userId){
        ActivityBarrageMessage msg = new ActivityBarrageMessage();
        msg.setActivityId(activityInfo.getActivityId());
        msg.setUserId(userId);
        msg.setContent(content);
        msg.setPostTime(System.currentTimeMillis());
        msg.setInsertOption();
        long size;
        synchronized (barrageLock){
            newNum++;
            msg.setContentId(contentId.incrementAndGet());
            messageList.add(msg);
            size = messageList.size();
        }
        ActivityBulletScreenMgr.getLogger().info("activityId {} bullet message size {}", activityInfo.getActivityId(), size);
        return msg;
    }

    /**
     * 添加待推送玩家
     * @param userId
     */
    public void addMsgListener(long userId){
        if(userId > 0 && !userIdSet.contains(userId)) {
            userIdSet.add(userId);
        }
    }

    /**
     * 获取弹幕
     * @return
     */
    public List<ActivityBarrageMessage> getMessageList(){
        synchronized (barrageLock){
            return new ArrayList<>(messageList);
        }
    }

    /**
     * 同步弹幕给客户端
     */
    public void syncBarrageMessageToClient(){
        if(activityInfo == null || DateHelper.getCurrentSecond() > activityInfo.getEndShowTime()){
            return;
        }
        int needSyncSize;
        synchronized (barrageLock){
            needSyncSize = newNum;
            newNum = 0;
            if(messageList.size() > 0) {
                lastSyncContentId = messageList.get(messageList.size() - 1).getContentId();
            }else {
                lastSyncContentId = 0;
            }
        }
        if(needSyncSize > 0 && lastSyncContentId > 0){
            List<ActivityBarrageMessage> allList = getMessageList();
            List<ActivityBarrageMessage> syncList = new ArrayList<>();
            long zeroTime = LocalDateTimeHelper.getZeroTimeTimeStamp();
            int len = allList.size();
            for(int i = len -1; i >= 0 && needSyncSize > 0; i--){
                ActivityBarrageMessage msg = allList.get(i);
                if(msg.getContentId() <= lastSyncContentId){
                    syncList.add(msg);
                    needSyncSize--;
                }
                //不取过期数据
                if(msg.getPostTime() < zeroTime){
                    syncList.remove(msg);
                    break;
                }
            }
            if(syncList.size() > 0){
                Collections.reverse(syncList);
                Iterator<Long> iterator = userIdSet.iterator();
                while (iterator.hasNext()){
                    long userId = iterator.next();
                    GamePlayer player = GamePlayerMgr.getOnlinePlayer(userId);
                    if(player != null){
                        BulletScreenProto.BulletScreenContentListRespMsg.Builder syncMsg = ActivityBulletScreenMgr.getMsgListBuilder(syncList);
                        syncMsg.setActivityId(activityInfo.getActivityId());
                        player.sendPacket(Protocol.U_ACTIVITY_SYNC_BULLET_SCREEN_COMMENTS, syncMsg);
                    }else {
                        iterator.remove();
                    }
                }
            }
        }
    }

    /**
     * 清理过期数据
     */
    public void removeOutTimeMsg(){
        if(activityInfo == null){
            return;
        }
        long zeroTimeStamp = LocalDateTimeHelper.getZeroTimeTimeStamp();
        synchronized (barrageLock){
            Iterator<ActivityBarrageMessage> iterator = messageList.iterator();
            while (iterator.hasNext()){
                ActivityBarrageMessage msg = iterator.next();
                if(msg.getPostTime() < zeroTimeStamp){
                    iterator.remove();
                }
            }
        }
    }

    /**
    * 描述：修改玩家弹幕内容
    * 作者：zrq
    * 时间：2022/8/5
    * 参数：
    玩家编号，变更内容
    * 返回值：操作码
    **/
    public int changePlayerMsg(long userId, String content, long contentId){
        if(activityInfo == null){
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }
        synchronized (barrageLock){
            Iterator<ActivityBarrageMessage> iterator = messageList.iterator();
            while (iterator.hasNext()){
                ActivityBarrageMessage msg = iterator.next();
                if(msg.getUserId() == userId && msg.getContentId() == contentId){
                    msg.setContent(content);
                }
            }
        }
        return 0;
    }

    /**
    * 描述：查询弹幕内容
    * 作者：zrq
    * 时间：2022/8/23
    * 参数：

    * 返回值：
    **/
    public JSONArray queryPlayerMsg(long userId){
        JSONArray dataArray = new JSONArray();
        if(activityInfo == null){
            return dataArray;
        }
        synchronized (barrageLock){
            Iterator<ActivityBarrageMessage> iterator = messageList.iterator();
            while (iterator.hasNext()){
                ActivityBarrageMessage msg = iterator.next();
                if(msg.getUserId() == userId){
                    JSONObject msgObj = new JSONObject();
                    msgObj.put("contentId", msg.getContentId());
                    msgObj.put("content", msg.getContent());
                    dataArray.add(msgObj);
                }
            }
        }
        return dataArray;
    }
}
